package com.jingxuan.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 搜索关键词处理器
 * 提供智能的关键词分析和处理功能
 */
public class SearchKeywordProcessor {

    /**
     * 处理搜索关键词，返回处理后的关键词信息
     */
    public static KeywordInfo processKeyword(String keyword) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return new KeywordInfo("", "", "", "", "", "", "");
        }

        String cleanKeyword = keyword.trim();
        
        // 检查是否为品牌+产品类型的组合
        BrandTypePair brandTypePair = extractBrandAndType(cleanKeyword);
        
        // 如果是品牌+产品类型组合，使用特殊处理
        if (brandTypePair != null) {
            return processBrandTypeKeyword(brandTypePair);
        }
        
        // 移除常见的品牌后缀和前缀
        cleanKeyword = removeCommonAffixes(cleanKeyword);
        
        // 生成精确匹配关键词
        String exactKeyword = cleanKeyword;
        
        // 生成前缀匹配关键词
        String prefixKeyword = cleanKeyword + "%";
        
        // 生成模糊匹配关键词
        String fuzzyKeyword = "%" + cleanKeyword + "%";
        
        // 生成类型匹配关键词（用于商品类型字段）
        String typeExactKeyword = cleanKeyword;
        String typePrefixKeyword = cleanKeyword + "%";
        
        // 生成更精确的模糊匹配关键词（避免过度匹配）
        String preciseFuzzyKeyword = generatePreciseFuzzyKeyword(cleanKeyword);
        
        return new KeywordInfo(cleanKeyword, exactKeyword, prefixKeyword, fuzzyKeyword,
                              typeExactKeyword, typePrefixKeyword, preciseFuzzyKeyword);
    }
    
    /**
     * 品牌和产品类型组合的封装类
     */
    public static class BrandTypePair {
        private final String brand;
        private final String type;
        private final String originalKeyword;
        
        public BrandTypePair(String brand, String type, String originalKeyword) {
            this.brand = brand;
            this.type = type;
            this.originalKeyword = originalKeyword;
        }
        
        public String getBrand() {
            return brand;
        }
        
        public String getType() {
            return type;
        }
        
        public String getOriginalKeyword() {
            return originalKeyword;
        }
    }
    
    /**
     * 提取品牌和产品类型组合
     */
    private static BrandTypePair extractBrandAndType(String keyword) {
        // 常见的产品类型列表
        List<String> productTypes = Arrays.asList(
            "手机", "电脑", "笔记本", "平板", "耳机", "音箱", "手表", "相机",
            "电视", "投影仪", "路由器", "键盘", "鼠标", "显示器", "充电器",
            "男装", "女装", "童装", "服装", "衣服", "上衣", "裤子", "裙子",
            "外套", "夹克", "衬衫", "T恤", "毛衣", "羽绒服", "大衣",
            "沙发", "床", "桌子", "椅子", "衣柜", "书架", "灯具", "地毯",
            "洗面奶", "面膜", "爽肤水", "乳液", "面霜", "精华", "口红", "粉底",
            "零食", "饮料", "牛奶", "咖啡", "茶叶", "巧克力", "饼干", "蛋糕"
        );
        
        // 常见的品牌列表
        List<String> brands = Arrays.asList(
            "苹果", "Apple", "华为", "小米", "OPPO", "vivo", "三星", "一加", "荣耀", "realme",
            "联想", "ThinkPad", "戴尔", "Dell", "惠普", "HP", "华硕", "ASUS", "宏碁", "Acer",
            "索尼", "Sony", "尼康", "Nikon", "佳能", "Canon", "富士", "Fujifilm",
            "耐克", "Nike", "阿迪达斯", "Adidas", "优衣库", "UNIQLO", "ZARA", "H&M",
            "海尔", "美的", "格力", "TCL", "海信", "小米", "小天鹅", "奥克斯",
            "欧莱雅", "L'Oreal", "雅诗兰黛", "Estee Lauder", "兰蔻", "Lancome", "香奈儿", "Chanel",
            "茅台", "五粮液", "剑南春", "泸州老窖", "汾酒", "洋河", "古井贡酒"
        );
        
        // 检查关键词是否以产品类型结尾
        for (String type : productTypes) {
            if (keyword.endsWith(type) && keyword.length() > type.length()) {
                String potentialBrand = keyword.substring(0, keyword.length() - type.length());
                
                // 检查潜在品牌是否在品牌列表中
                for (String brand : brands) {
                    if (potentialBrand.contains(brand)) {
                        return new BrandTypePair(brand, type, keyword);
                    }
                }
            }
        }
        
        return null;
    }
    
    /**
     * 处理品牌+产品类型组合的关键词
     */
    private static KeywordInfo processBrandTypeKeyword(BrandTypePair brandTypePair) {
        String brand = brandTypePair.getBrand();
        String type = brandTypePair.getType();
        String originalKeyword = brandTypePair.getOriginalKeyword();
        
        // 生成品牌+产品类型的精确匹配关键词
        String exactKeyword = originalKeyword;
        
        // 生成品牌+产品类型的前缀匹配关键词
        String prefixKeyword = originalKeyword + "%";
        
        // 生成品牌+产品类型的模糊匹配关键词
        String fuzzyKeyword = "%" + originalKeyword + "%";
        
        // 生成产品类型的精确匹配关键词
        String typeExactKeyword = type;
        
        // 生成产品类型的前缀匹配关键词
        String typePrefixKeyword = type + "%";
        
        // 生成品牌+产品类型的精确匹配SQL条件
        String preciseFuzzyKeyword = "(product_name LIKE '" + brand + "%" + type + "%' OR " +
                                     "product_name LIKE '%" + brand + "%" + type + "' OR " +
                                     "product_name LIKE '" + brand + "%' AND product_name LIKE '%" + type + "%')";
        
        return new KeywordInfo(originalKeyword, exactKeyword, prefixKeyword, fuzzyKeyword,
                              typeExactKeyword, typePrefixKeyword, preciseFuzzyKeyword, brand, type);
    }

    /**
     * 移除常见的品牌后缀和前缀，提高匹配精度
     */
    private static String removeCommonAffixes(String keyword) {
        // 常见的前缀列表
        List<String> prefixes = Arrays.asList(
            "官方", "正品", "新款", "老款", "进口", "国产", "原装"
        );
        
        // 常见的后缀列表
        List<String> suffixes = Arrays.asList(
            "手机", "款", "版", "代", "型号", "系列", "套装", "套装版",
            "官方版", "标配版", "高配版", "低配版", "珍藏版", "限量版"
        );
        
        String result = keyword;
        
        // 移除前缀 - 按长度排序，优先移除更长的前缀
        prefixes.sort((a, b) -> b.length() - a.length());
        for (String prefix : prefixes) {
            if (result.startsWith(prefix)) {
                result = result.substring(prefix.length()).trim();
                break; // 只移除一个前缀
            }
        }
        
        // 移除后缀 - 按长度排序，优先移除更长的后缀
        suffixes.sort((a, b) -> b.length() - a.length());
        for (String suffix : suffixes) {
            if (result.endsWith(suffix) && result.length() > suffix.length()) {
                result = result.substring(0, result.length() - suffix.length()).trim();
                break; // 只移除一个后缀
            }
        }
        
        return result.isEmpty() ? keyword : result;
    }
    
    /**
     * 生成更精确的模糊匹配关键词，避免过度匹配
     * 例如：搜索"男装"时，应该匹配"男装外套"，但不应该匹配"男士洗面奶"
     */
    private static String generatePreciseFuzzyKeyword(String keyword) {
        // 对于特定类别的关键词，添加空格或常见分隔符，提高匹配精度
        if (isCategoryKeyword(keyword)) {
            return "%" + keyword + " %" + " OR " +
                   "product_name LIKE '" + keyword + "%' OR " +
                   "product_name LIKE '% " + keyword + "'";
        }
        
        // 对于其他关键词，使用标准模糊匹配
        return "%" + keyword + "%";
    }
    
    /**
     * 判断是否为类别关键词（需要精确匹配的关键词）
     */
    private static boolean isCategoryKeyword(String keyword) {
        // 服装类关键词
        List<String> clothingKeywords = Arrays.asList(
            "男装", "女装", "童装", "服装", "衣服", "上衣", "裤子", "裙子",
            "外套", "夹克", "衬衫", "T恤", "毛衣", "羽绒服", "大衣",
            "牛仔裤", "休闲裤", "短裤", "运动服", "西装", "礼服"
        );
        
        // 电子产品类关键词
        List<String> electronicsKeywords = Arrays.asList(
            "手机", "电脑", "笔记本", "平板", "耳机", "音箱", "手表", "相机",
            "电视", "投影仪", "路由器", "键盘", "鼠标", "显示器", "充电器"
        );
        
        // 家居用品类关键词
        List<String> homeKeywords = Arrays.asList(
            "沙发", "床", "桌子", "椅子", "衣柜", "书架", "灯具", "地毯",
            "窗帘", "床垫", "枕头", "被子", "毛巾", "浴巾", "拖鞋"
        );
        
        // 美妆护肤类关键词
        List<String> beautyKeywords = Arrays.asList(
            "洗面奶", "面膜", "爽肤水", "乳液", "面霜", "精华", "口红", "粉底",
            "眼影", "睫毛膏", "卸妆水", "防晒霜", "洗发水", "护发素", "沐浴露"
        );
        
        // 食品类关键词
        List<String> foodKeywords = Arrays.asList(
            "零食", "饮料", "牛奶", "咖啡", "茶叶", "巧克力", "饼干", "蛋糕",
            "糖果", "坚果", "水果", "蔬菜", "肉类", "海鲜", "调料"
        );
        
        return clothingKeywords.contains(keyword) ||
               electronicsKeywords.contains(keyword) ||
               homeKeywords.contains(keyword) ||
               beautyKeywords.contains(keyword) ||
               foodKeywords.contains(keyword);
    }
    
    /**
     * 获取不相关匹配的关键词列表（用于惩罚机制）
     */
    public static List<String> getIrrelevantMatchPatterns(String keyword) {
        List<String> patterns = new ArrayList<>();
        
        // 服装类关键词的不相关匹配模式
        if (keyword.equals("男装")) {
            patterns.add("男士");
        } else if (keyword.equals("女装")) {
            patterns.add("女士");
        } else if (keyword.equals("童装")) {
            patterns.add("儿童");
        }
        
        // 电子产品类关键词的不相关匹配模式
        if (keyword.equals("手机")) {
            patterns.add("手机壳");
            patterns.add("手机膜");
            patterns.add("手机支架");
        } else if (keyword.equals("电脑")) {
            patterns.add("电脑包");
            patterns.add("电脑桌");
            patterns.add("电脑椅");
        }
        
        // 美妆护肤类关键词的不相关匹配模式
        if (keyword.equals("洗面奶")) {
            patterns.add("洗面奶");
        } else if (keyword.equals("洗发水")) {
            patterns.add("洗发水");
        }
        
        return patterns;
    }

    /**
     * 分词处理，将复合关键词拆分为多个部分
     */
    public static List<String> tokenizeKeyword(String keyword) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return new ArrayList<>();
        }
        
        String cleanKeyword = keyword.trim();
        List<String> tokens = new ArrayList<>();
        
        // 简单的分词策略：按空格、连字符等分隔符拆分
        tokens.addAll(Arrays.asList(cleanKeyword.split("[\\s\\-_]+")));
        
        // 对于中文，尝试按常见词汇边界拆分
        if (containsChinese(cleanKeyword)) {
            tokens.addAll(tokenizeChinese(cleanKeyword));
        }
        
        // 去重并过滤空字符串
        return tokens.stream()
                .distinct()
                .filter(token -> !token.trim().isEmpty())
                .collect(Collectors.toList());
    }

    /**
     * 检查字符串是否包含中文字符
     */
    private static boolean containsChinese(String text) {
        return text.matches(".*[\\u4e00-\\u9fa5].*");
    }

    /**
     * 简单的中文分词策略
     */
    private static List<String> tokenizeChinese(String chineseText) {
        List<String> tokens = new ArrayList<>();
        
        // 常见的电子产品词汇
        List<String> commonTerms = Arrays.asList(
            "手机", "苹果", "华为", "小米", "OPPO", "vivo", "三星", "一加",
            "iPhone", "iPad", "MacBook", "电脑", "笔记本", "平板",
            "耳机", "音箱", "手表", "相机", "电视", "投影仪"
        );
        
        // 检查文本中是否包含常见词汇
        for (String term : commonTerms) {
            if (chineseText.contains(term)) {
                tokens.add(term);
            }
        }
        
        // 如果没有找到常见词汇，尝试按2-3个字符拆分
        if (tokens.isEmpty()) {
            int length = chineseText.length();
            if (length >= 2) {
                // 添加2字符组合
                for (int i = 0; i <= length - 2; i++) {
                    tokens.add(chineseText.substring(i, i + 2));
                }
            }
            if (length >= 3) {
                // 添加3字符组合
                for (int i = 0; i <= length - 3; i++) {
                    tokens.add(chineseText.substring(i, i + 3));
                }
            }
        }
        
        return tokens;
    }

    /**
     * 关键词信息封装类
     */
    public static class KeywordInfo {
        private final String originalKeyword;
        private final String exactKeyword;
        private final String prefixKeyword;
        private final String fuzzyKeyword;
        private final String typeExactKeyword;
        private final String typePrefixKeyword;
        private final String preciseFuzzyKeyword;
        private final String brand;
        private final String type;

        public KeywordInfo(String originalKeyword, String exactKeyword, String prefixKeyword, String fuzzyKeyword,
                          String typeExactKeyword, String typePrefixKeyword, String preciseFuzzyKeyword) {
            this.originalKeyword = originalKeyword;
            this.exactKeyword = exactKeyword;
            this.prefixKeyword = prefixKeyword;
            this.fuzzyKeyword = fuzzyKeyword;
            this.typeExactKeyword = typeExactKeyword;
            this.typePrefixKeyword = typePrefixKeyword;
            this.preciseFuzzyKeyword = preciseFuzzyKeyword;
            this.brand = null;
            this.type = null;
        }

        public KeywordInfo(String originalKeyword, String exactKeyword, String prefixKeyword, String fuzzyKeyword,
                          String typeExactKeyword, String typePrefixKeyword, String preciseFuzzyKeyword,
                          String brand, String type) {
            this.originalKeyword = originalKeyword;
            this.exactKeyword = exactKeyword;
            this.prefixKeyword = prefixKeyword;
            this.fuzzyKeyword = fuzzyKeyword;
            this.typeExactKeyword = typeExactKeyword;
            this.typePrefixKeyword = typePrefixKeyword;
            this.preciseFuzzyKeyword = preciseFuzzyKeyword;
            this.brand = brand;
            this.type = type;
        }

        public String getOriginalKeyword() {
            return originalKeyword;
        }

        public String getExactKeyword() {
            return exactKeyword;
        }

        public String getPrefixKeyword() {
            return prefixKeyword;
        }

        public String getFuzzyKeyword() {
            return fuzzyKeyword;
        }
        
        public String getTypeExactKeyword() {
            return typeExactKeyword;
        }
        
        public String getTypePrefixKeyword() {
            return typePrefixKeyword;
        }
        
        public String getPreciseFuzzyKeyword() {
            return preciseFuzzyKeyword;
        }
        
        public String getBrand() {
            return brand;
        }
        
        public String getType() {
            return type;
        }
    }
}